package com.hzw.saas.common.verify.service.impl;

import java.util.Collection;
import java.util.Objects;

import com.hzw.saas.common.verify.config.EmailSmtpConfig;
import com.hzw.saas.common.verify.service.IEmailService;
import com.hzw.saas.common.verify.util.TemplateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.mail.MailAccount;
import cn.hutool.extra.mail.MailUtil;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @author zzl
 * @since 09/02/2021
 */
@Slf4j
public class SmtpEmailServiceImpl implements IEmailService {

    private final EmailSmtpConfig config;
    private MailAccount account;

    private static final String VERIFY_TEMPLATE_PATH = "template/emailTemplate.html";
    private final String verifyCodeTemplate;

    public SmtpEmailServiceImpl(EmailSmtpConfig config) {
        this.config = config;
        try {
            log.debug("邮件发送账户初始化... from: {}", config.getFrom());
            this.account = this.createAccount(this.config);
            log.debug("邮件发送账户初始化完成. from: {}", config.getFrom());
        } catch (Exception e) {
            log.error("邮件发送账户初始化失败: ".concat(e.getMessage()));
        }
        this.verifyCodeTemplate = TemplateUtil.getTemplate(VERIFY_TEMPLATE_PATH);
    }

    @Override
    public void send(String to, String subject, String content, boolean isHTML) {
        MailAccount account = getAccount();
        log.debug("发送邮件 from {} to {} ...", account.getFrom(), to);
        MailUtil.send(account, to, subject, content, isHTML);
    }

    @Override
    public void send(Collection<String> tos, Collection<String> ccs, Collection<String> bccs, String subject, String content, boolean isHtml) {
        MailAccount account = getAccount();
        log.debug("发送邮件 from {} to {} ...", account.getFrom(), JSONUtil.toJsonStr(tos));
        MailUtil.send(account, tos, ccs, bccs, subject, content, isHtml);
    }

    @Override
    public String sendVerifyCode(String to, String subject, String code) {
        MailAccount account = getAccount();
        String content = this.verifyCodeTemplate.replace("{{code}}", code);
        log.debug("发送邮件验证码 from {} to {}, code: {} ...", account.getFrom(), to, code);
        MailUtil.send(account, to, subject, content, true);
        return code;
    }

    // ================================================ private method ================================================ //

    private MailAccount createAccount(EmailSmtpConfig config) {
        Assert.notBlank(config.getFrom(), "邮件发件人配置为空");
        Assert.notBlank(config.getPass(), "邮件密码配置为空");
        log.debug("创建邮件发送账户{host: {}, from: {}}....", config.getHost(), config.getFrom());
        MailAccount account = new MailAccount();
        account.setFrom(config.getFrom());
        account.setPass(config.getPass());
        if (StrUtil.isNotBlank(config.getHost()))
            account.setHost(config.getHost());
        if (Objects.nonNull(config.getPort()))
            account.setPort(config.getPort());
        if (StrUtil.isNotBlank(config.getUser()))
            account.setUser(config.getUser());
        if (Objects.nonNull(config.getAuth()))
            account.setAuth(config.getAuth());
        if (Objects.nonNull(config.getSslEnable()))
            account.setSslEnable(config.getSslEnable());

        return account;
    }

    private MailAccount getAccount() {
        if (Objects.isNull(this.account)) {
            this.account = this.createAccount(this.config);
        }
        return this.account;
    }
}
